package org.totoro.analysis;

import com.sun.tools.classfile.Opcode;
import org.objectweb.asm.*;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

public class MyClassVisitor extends ClassVisitor {
    private List<MethodInfo> methods = new ArrayList<>();
    private String cname;

    public MyClassVisitor(String className) throws IOException {
        super(Opcodes.ASM7, new ClassWriter(ClassReader.SKIP_DEBUG));
        ClassReader cr = new ClassReader(className);
        cr.accept(this, ClassReader.SKIP_DEBUG);
    }

    public List<MethodInfo> getMethods() {
        return methods;
    }

    @Override
    public void visit(final int version, final int access, final String cname, final String signature,
                      final String superName, final String[] interfaces) {
        this.cname = cname;
        super.visit(version, access, cname, signature, superName, interfaces);
    }

    @Override
    public MethodVisitor visitMethod(final int access, final String mname, final String descriptor,
                                     final String signature, final String[] exceptions) {
        return new MyMethodVisitor(mname, descriptor,
                cv.visitMethod(access, mname, descriptor, signature, exceptions));
    }

    private class MyMethodVisitor extends MethodVisitor {
        private MethodInfo method;

        public MyMethodVisitor(String mname, String descriptor, MethodVisitor mv) {
            super(Opcodes.ASM7, mv);
            method = new MethodInfo(cname, mname, descriptor);
            methods.add(method);
        }

        @Override
        public void visitMethodInsn(final int opcode, final String invokeCname, final String invokeMname,
                                    final String InvokeDescriptor, final boolean isInterface) {
            method.addInvoke(new MethodInfo(invokeCname, invokeMname, InvokeDescriptor));
            super.visitMethodInsn(opcode, invokeCname, invokeMname, InvokeDescriptor, isInterface);
        }

        @Override
        public void visitInsn(int opcode) {
            super.visitInsn(opcode);
        }

        @Override
        public void visitTypeInsn(int opcode, String type) {
            Opcode opcode1 = Opcode.get(opcode);
            System.out.println(opcode1.kind);
            super.visitTypeInsn(opcode, type);

        }
    }
}